利用 CURL 进行数据抓取总结

  1. 1. POST
  2. 2. Referer
  3. 3. cookie支持
  4. 4. 压缩网页gzip
  5. 5. SSL
  6. 6. 代理
  7. 7. 多线程
  8. 8. 跳转
  9. 9. 上传文件

POST

CURLOPT_POST 的设置可以指定当前提交是否为POST方式

CURLOPT_POSTFIELDS则用于设定提交的参数,可以是参数串,也可以是参数数组

Referer

对于一些程序,它可能判断来源网址,如果发现referer不是自己的网站,则拒绝访问,这时候,我们就需要添加CURLOPT_REFERER参数

cookie支持

对于模拟登录的应用,单单提交参数和模拟来路并不能解决问题,这时候我们就需要保存或者提交相应的Cookie参数

CURLOPT_COOKIE: 直接使用字符串方式提交cookie参数

CURLOPT_COOKIEFILE: 使用文件方式提交cookie参数

CURLOPT_COOKIEJAR: 保存提交后反馈的cookie数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
header("content-Type: text/html; charset=UTF-8");
$cookie_file = tempnam('./temp', 'cookie');
$login_url="http://somesite.com/login.php";
$post_fields="cktime=36000&step=2&pwuser=username&pwpwd=password";
//提交登录表单请求
$ch=curl_init($login_url);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$post_fields);
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookie_file); //存储提交后得到的cookie数据
curl_exec($ch);
curl_close($ch);
//登录成功后,获取bbs首页数据
$url="http://somesite.com/index.php";
$ch=curl_init($url);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_COOKIEFILE,$cookie_file); //使用提交后得到的cookie数据做参数
$contents=curl_exec($ch);
curl_close($ch);
//转码显示
echo iconv('gbk', 'UTF-8', $contents);

压缩网页gzip

有些没有接触过压缩页面的朋友估计会在这里被坑死,因为他们会发现采集回来的内容是乱码,并且无论使用iconv还是强大的mb_convert_encoding都无法还原数据,然后又没有概念,各种抓狂却找不到方法

1
2
3
4
5
6
7
$url = 'http://news.sohu.com/';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出
curl_setopt($ch, CURLOPT_ENCODING, "gzip"); //指定gzip压缩
$content = curl_exec($ch); //执行并存储结果
curl_close($ch);
echo $content;

支持的编码有”identity”,”deflate”和”gzip”

如果为空字符串””,请求头会发送所有支持的编码类型。后面一句表明,使用curl_setopt($ch, CURLOPT_ENCODING, “”);也是可以的,但是不能不加这个参数。

SSL

var_dump(curl_error($ch));的方法打印错误提示,然后根据错误提示查找相应的解决方案。比如SSL错误常见提示:SSL certificate problem: unable to get local issuer certificate,这时候,我们就需要利用参数:CURLOPT_SSL_VERIFYPEER 和 CURLOPT_SSL_VERIFYHOST 来禁用SSL证书的验证,我尝试过只使用CURLOPT_SSL_VERIFYPEER参数禁用失败,所以大家最好同时使用两个参数。

代理

国内存在万恶的墙,所以,假如我们需要获取某些被墙数据时,就需要用到国外代理服务器;
又或者我们需要采集大量数据时,需要不断切换IP,也会用到代理。

使用代理在PHP cURL里面有几个相对应的参数:CURLOPT_PROXY、CURLOPT_PROXYPORT 和 CURLOPT_PROXYUSERPWD,还有另外几个,这里不列举。

CURLOPT_PROXY 指定代理IP参数

CURLOPT_PROXYPORT 指定代理端口参数

CURLOPT_PROXYUSERPWD 指定需要验证的代理的账号密码,”[username]:[password]”格式的字符串

多线程

curl_multi

跳转

CURLOPT_FOLLOWLOCATION

上传文件

全部数据使用HTTP协议中的”POST”操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。
这个参数可以通过urlencoded后的query字符串或使用一个以字段名为键值,字段数据为值的数组。
如果value是一个数组,Content-Type头将会被设置成multipart/form-data。

关于CURLOPT_POSTFIELDS的赋值,另外补充一句描述:

传递一个URL-encoded字符串时,数据会被编码成 application/x-www-form-urlencoded
传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成 multipart/form-data
即:

1
2
3
4
5
6
7
curl_setopt($ch, CURLOPT_POSTFIELDS, 'param1=val1&param2=val2&...');
// 相当于
// <form method="post" action="upload.php">
curl_setopt($ch, CURLOPT_POSTFIELDS, array('param1' => 'val1', 'param2' => 'val2', ...));
// 相当于
// <form method="post" action="upload.php" enctype="multipart/form-data">